package user

import (
	v1 "gitee.com/sweetsunnyflower/carpooling-server-go/app/http/controllers/api/v1"
	"gitee.com/sweetsunnyflower/carpooling-server-go/app/models/blacklist"
	"gitee.com/sweetsunnyflower/carpooling-server-go/app/models/trip"
	"gitee.com/sweetsunnyflower/carpooling-server-go/app/models/user"
	"gitee.com/sweetsunnyflower/carpooling-server-go/app/models/user_follow"
	"gitee.com/sweetsunnyflower/carpooling-server-go/app/policies"
	"gitee.com/sweetsunnyflower/carpooling-server-go/app/requests"
	"github.com/gofiber/fiber/v2"
	"github.com/spf13/cast"
)

type UsersController struct {
	v1.BaseController
}

func (controller *UsersController) Show(c *fiber.Ctx) error {

	userId := controller.Auth(c)
	userModel := user.GetWithDriverAndPassenger(userId)

	if userModel.Driver != nil {
		// 查询司机相关数据
		userModel.Driver.TripsCount = trip.GetTripsCountByUserId(userId)
	}

	if userModel.Passenger != nil {
		userModel.Passenger.FollowsCount = user_follow.GetFollowsCountByUserId(userId)
		userModel.Passenger.BlacksCount = blacklist.GetBlackCountByUserIdForPassenger(userId)
	}

	if userModel.ID == 0 {
		return controller.NotFound(c)
	}

	return controller.Json(c, userModel)
}

func (controller *UsersController) Update(c *fiber.Ctx) error {

	userId := controller.Auth(c)

	userModel := user.Get(userId)

	if userModel.ID == 0 {
		return controller.NotFound(c)
	}

	request := new(requests.UserRequest)

	if errors := requests.ValidateUser(c, request); len(errors) > 0 {
		return controller.ValidationError(c, errors)
	}

	userModel.Avatar = request.Avatar
	userModel.Name = request.Name
	userModel.Email = request.Email
	userModel.Phone = request.Phone
	userModel.Gender = request.Gender

	rowsAffected := userModel.Save()
	if rowsAffected > 0 {
		return controller.Success(c)
	} else {
		return controller.Faield(c, "更新失败")
	}
}

func (controller *UsersController) Delete(c *fiber.Ctx) error {

	userModel := user.Get(cast.ToUint64(c.Query("id")))
	if userModel.ID == 0 {
		return controller.NotFound(c)
	}

	userId := controller.Auth(c)

	if ok := policies.CanModifyUser(userId, userModel); !ok {
		return controller.Forbidden(c)
	}

	rowsAffected := userModel.Delete()
	if rowsAffected > 0 {
		return controller.Success(c)
	}

	return controller.Faield(c, "删除失败")
}
